//! Panic 示例
//!
//! panic! 宏用于程序无法继续执行的情况，会立即终止程序并显示错误信息。

/// 使用 panic! 宏
pub fn panic_basics() {
    // 直接调用 panic!
    // panic!("程序出错了！");

    // 在条件不满足时调用 panic!
    let value = 10;
    if value < 0 {
        panic!("值不能为负数: {}", value);
    }

    println!("panic 基础示例: 没有触发 panic");
}

/// 使用 panic! 处理不可恢复错误
pub fn unrecoverable_errors() {
    // 访问超出索引范围的元素会触发 panic
    let v = vec![1, 2, 3];
    // v[99]; // 这会导致 panic

    println!("不可恢复错误示例: 没有触发 panic");
}

/// 在测试中使用 panic
#[cfg(test)]
pub fn panic_in_tests() {
    // 在测试中，panic 通常表示测试失败
    assert_eq!(2 + 2, 4);
    // assert_eq!(2 + 2, 5); // 这会导致测试失败（panic）

    println!("测试中使用 panic 示例");
}

/// 使用 Result 而不是 panic
pub fn prefer_result_over_panic() {
    // 更好的方式是返回 Result 而不是直接 panic
    fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
        if divisor == 0.0 {
            // 返回错误而不是 panic
            Err(String::from("除数不能为零"))
        } else {
            Ok(dividend / divisor)
        }
    }

    match divide(10.0, 0.0) {
        Ok(result) => println!("结果: {}", result),
        Err(e) => println!("错误: {}", e),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_panic_basics() {
        panic_basics();
    }

    #[test]
    #[should_panic]
    fn test_should_panic() {
        panic!("这个测试应该 panic");
    }

    #[test]
    fn test_prefer_result_over_panic() {
        prefer_result_over_panic();
    }
}
